﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Data;
using System.Drawing;
using System.Reflection;


    //*******************************************************************
    // Purpose: Class dùng sort item cho ListView
    // Notes: 
    // History:
    // [Programer] [DD-MMM-YYYY] [Action]
    // LuanNH Unknow Created
    //******************************************************************* 

    public class ListViewColumnSorter : System.Collections.IComparer
    {

        private int ColumnToSort;
        private SortOrder OrderOfSort;

        private CaseInsensitiveComparer ObjectCompare;
        public ListViewColumnSorter()
        {
            // Initialize the column to '-1'.
            ColumnToSort = -1;

            // Initialize the sort order to 'none'.
            OrderOfSort = SortOrder.None;

            // Initialize the CaseInsensitiveComparer object.
            //ObjectCompare = New CaseInsensitiveComparer()
        }

        public void Reset()
        {
            ColumnToSort = -1;
            OrderOfSort = SortOrder.None;
        }

        public int Compare(object x, object y)
        {
            if (ColumnToSort == -1)
                return 0;

            int compareResult = 0;
            ListViewItem listviewX = default(ListViewItem);
            ListViewItem listviewY = default(ListViewItem);
            object sValueX = null;
            object sValueY = null;
            // Cast the objects to be compared to ListViewItem objects.
            listviewX = (ListViewItem)x;
            listviewY = (ListViewItem)y;
            //
            string sDataType = ((ListViewHeader)listviewX.ListView.Columns[ColumnToSort]).DataType;
            // Compare the two items.
            if (listviewX.SubItems.Count > ColumnToSort && listviewY.SubItems.Count > ColumnToSort)
            {
                sValueX = listviewX.SubItems[ColumnToSort].Tag;
                if (sValueX == null)
                    sValueX = listviewX.SubItems[ColumnToSort].Text;
                sValueY = listviewY.SubItems[ColumnToSort].Tag;
                if (sValueY == null)
                    sValueY = listviewY.SubItems[ColumnToSort].Text;
                //
                if ("DateTime".Contains(sDataType))
                {
                    compareResult = System.DateTime.Compare(System.DateTime.Parse(sValueX.ToString()), System.DateTime.Parse(sValueY.ToString()));
                }
                else if ("Int16;Int32;Int64;Double;Decimal;".Contains(sDataType))
                {
                    compareResult = decimal.Compare(decimal.Parse(sValueX.ToString()), decimal.Parse(sValueY.ToString()));
                }
                else
                {
                    //compareResult = ObjectCompare.Compare(sValueX, sValueY)
                    compareResult = string.Compare(sValueX.ToString(), sValueY.ToString(), true);
                }
            }
            else
            {
                return 0;
            }
            // Calculate the correct return value based on the object 
            // comparison.
            if ((OrderOfSort == SortOrder.Ascending))
            {
                // Ascending sort is selected, return typical result of 
                // compare operation.
                return compareResult;
            }
            else if ((OrderOfSort == SortOrder.Descending))
            {
                // Descending sort is selected, return negative result of 
                // compare operation.
                return (-compareResult);
            }
            else
            {
                // Return '0' to indicate that they are equal.
                return 0;
            }
        }

        public int SortColumn
        {

            get { return ColumnToSort; }
            set { ColumnToSort = value; }
        }

        public SortOrder Order
        {

            get { return OrderOfSort; }
            set { OrderOfSort = value; }
        }
    }

    //*******************************************************************
    // Purpose: Class dùng để mở rộng 1 số thuộc tính cho ColumnHeader của ListView
    // Notes: Hỗ trợ việc DataBind cho ListView dễ dàng hơn
    // History:
    // [Programer] [DD-MMM-YYYY] [Action]
    // LuanNH Unknow Created
    //******************************************************************* 

    public class ListViewHeader : ColumnHeader
    {


        public ListViewHeader()
        {
        }

        public ListViewHeader(string _HeaderText, int _Width, string _DataField)
        {
            this.Text = _HeaderText;
            this.Width = _Width;
            DataField = _DataField;
        }

        public ListViewHeader(string _HeaderText, int _Width, string _DataField, HorizontalAlignment _Align)
        {
            this.Text = _HeaderText;
            this.Width = _Width;
            this.TextAlign = _Align;
            DataField = _DataField;
        }

        public ListViewHeader(string _HeaderText, string _DataField, bool _HiddenValue)
        {
            this.Text = _HeaderText;
            DataField = _DataField;
            KeepValue = _HiddenValue;
        }

        public ListViewHeader(string _HeaderText, string _DataField, bool _HiddenValue, string _StatusArray, string _StatusColor)
        {
            this.Text = _HeaderText;
            DataField = _DataField;
            KeepValue = _HiddenValue;
            StatusArray = _StatusArray;
            StatusColor = _StatusColor;
        }

        public ListViewHeader(string _HeaderText, string _DataField, string _StatusArray, string _StatusColor)
        {
            this.Text = _HeaderText;
            DataField = _DataField;
            StatusArray = _StatusArray;
            StatusColor = _StatusColor;
        }

        //Tên trường dữ liệu
        public string DataField;
        //Đánh dấu có lưu dữ liệu vào thuộc tính Tag của SubItem hay không (chủ yếu phục vụ việc sort)
        public bool KeepValue;
        //Chuỗi value của dữ liệu
        public string StatusArray;
        //Chuỗi màu tương ứng với value
        public string StatusColor;
        //
        //Kiểu dữ liệu (tự động gán khi DataBind)
        public string DataType;
        //Index của trường dữ liệu (tự động gán khi DataBind)
        public int DataIndex = -1;
    }

    public class ListViewHandle
    {
        //*******************************************************************
        // Purpose: Class dùng để handle ListView 
        // Notes: Hỗ trợ việc sort và copy data của ListView
        // History:
        // [Programer] [DD-MMM-YYYY] [Action]
        // LuanNH Unknow Created
        //******************************************************************* 
        private ListView withEventsField_objListView;
        private ListView objListView
        {
            get { return withEventsField_objListView; }
            set
            {
                if (withEventsField_objListView != null)
                {
                    withEventsField_objListView.DoubleClick -= objListView_DoubleClick;
                    withEventsField_objListView.ColumnClick -= objColumnClick;
                    withEventsField_objListView.SelectedIndexChanged -= objListView_SelectedIndexChanged;
                    withEventsField_objListView.DrawColumnHeader -= objListView_DrawColumnHeader;
                    withEventsField_objListView.DrawItem -= objListView_DrawItem;
                    withEventsField_objListView.DrawSubItem -= objListView_DrawSubItem;
                }
                withEventsField_objListView = value;
                if (withEventsField_objListView != null)
                {
                    withEventsField_objListView.DoubleClick += objListView_DoubleClick;
                    withEventsField_objListView.ColumnClick += objColumnClick;
                    withEventsField_objListView.SelectedIndexChanged += objListView_SelectedIndexChanged;
                    withEventsField_objListView.DrawColumnHeader += objListView_DrawColumnHeader;
                    withEventsField_objListView.DrawItem += objListView_DrawItem;
                    withEventsField_objListView.DrawSubItem += objListView_DrawSubItem;
                }
            }
        }
        private bool _AllowSort;
        private bool _AllowCopy;
        private ListViewColumnSorter lvwColumnSorter;

        private DataView _DataSource;
        public bool AllowSort
        {
            get { return _AllowSort; }
            set { _AllowSort = value; }
        }

        public bool AllowCopy
        {
            get { return _AllowCopy; }
            set { _AllowCopy = value; }
        }

        public ListViewHandle(ListView lv)
        {
            _AllowSort = false;
            _AllowCopy = false;
            objListView = lv;
            //
            Init_Control();
        }

        public ListViewHandle(ListView lv, bool bAllowSort)
        {
            _AllowSort = bAllowSort;
            _AllowCopy = false;
            objListView = lv;
            if (_AllowSort)
            {
                lvwColumnSorter = new ListViewColumnSorter();
                objListView.ListViewItemSorter = lvwColumnSorter;
            }
            //
            Init_Control();
        }

        public ListViewHandle(ListView lv, bool bAllowSort, bool bAllowCopy)
        {
            _AllowSort = bAllowSort;
            _AllowCopy = bAllowCopy;
            objListView = lv;
            if (_AllowSort)
            {
                lvwColumnSorter = new ListViewColumnSorter();
                objListView.ListViewItemSorter = lvwColumnSorter;
            }
            //
            Init_Control();
        }

        private MethodInvoker m_DbClickMethod;
        public void Row_DblClick(MethodInvoker DbClickMethod)
        {
            m_DbClickMethod = DbClickMethod;
        }

        private MethodInvoker m_SelectMethod;
        public void Row_Selected(MethodInvoker SelectMethod)
        {
            m_SelectMethod = SelectMethod;
        }

        private void Init_Control()
        {
            objListView.MultiSelect = false;
            objListView.View = View.Details;
            objListView.FullRowSelect = true;
            objListView.HideSelection = false;
            objListView.GridLines = true;
            //
            objListView.OwnerDraw = true;
        }

        private void objListView_DoubleClick(object sender, System.EventArgs e)
        {
            if (objListView.SelectedItems.Count > 0)
            {
                if ((m_DbClickMethod != null))
                    m_DbClickMethod.Invoke();
            }
        }

        private void objColumnClick(object sender, System.Windows.Forms.ColumnClickEventArgs e)
        {
            try
            {
                if (!_AllowSort)
                    return;
                // Determine if the clicked column is already the column that is 
                // being sorted.
                if ((e.Column == lvwColumnSorter.SortColumn))
                {
                    // Reverse the current sort direction for this column.
                    if ((lvwColumnSorter.Order == SortOrder.Ascending))
                    {
                        lvwColumnSorter.Order = SortOrder.Descending;
                    }
                    else
                    {
                        lvwColumnSorter.Order = SortOrder.Ascending;
                    }
                }
                else
                {
                    // Set the column number that is to be sorted; default to ascending.
                    lvwColumnSorter.SortColumn = e.Column;
                    lvwColumnSorter.Order = SortOrder.Ascending;
                }

                // Perform the sort with these new sort options.
                objListView.Sort();

            }
            catch (Exception ex)
            {
            }
        }

        public void Sort_Reset()
        {
            if ((lvwColumnSorter != null))
            {
                lvwColumnSorter.SortColumn = 0;
                lvwColumnSorter.Order = SortOrder.None;
            }
        }

        public object GetKeyValue()
        {
            if (objListView.SelectedItems.Count == 0)
            {
                return null;
            }
            else
            {
                return objListView.SelectedItems[0].Tag;
            }
        }

        public object GetRowValue(string sFieldName, int rowIndex)
        {
            if (_DataSource == null || rowIndex > _DataSource.Count - 1)
            {
                return null;
            }
            else
            {
                DataRow dr = GetRowData(rowIndex);
                if (dr == null)
                {
                    ListViewItem.ListViewSubItem itm = ListViewCommon.GetSubItem(objListView.Items[rowIndex], sFieldName);
                    if (itm == null)
                    {
                        return null;
                    }
                    else
                    {
                        if (itm.Tag == null)
                        {
                            return itm.Text;
                        }
                        else
                        {
                            return itm.Tag;
                        }
                    }
                }
                else
                {
                    return dr[sFieldName];
                }
            }
        }

        public object GetRowValue(string sFieldName)
        {
            if (objListView.SelectedItems.Count == 0)
            {
                return null;
            }
            else
            {
                return GetRowValue(sFieldName, objListView.SelectedItems[0].Index);
            }
        }

        public DataRow GetRowData()
        {
            if (objListView.SelectedItems.Count == 0)
            {
                return null;
            }
            else
            {
                return GetRowData(objListView.SelectedItems[0].Index);
            }
        }

        public DataRow GetRowData(int rowIndex)
        {
            if (_DataSource == null || rowIndex > _DataSource.Count - 1)
            {
                return null;
            }
            else
            {
                return _DataSource[rowIndex].Row;
            }
        }

        public void BindData(DataTable objDataTable, string sPK_Field, string sGroup_Field)
        {
            BindData(objDataTable, sPK_Field, sGroup_Field, null);
        }

        public void BindData(DataTable objDataTable, string sPK_Field, string sGroup_Field, ListItemInvoker itemInvoke)
        {
            BindData(objDataTable.DefaultView, sPK_Field, sGroup_Field, itemInvoke);
        }

        public void BindData(DataView objDataView, string sPK_Field, string sGroup_Field, ListItemInvoker itemInvoke)
        {
            _DataSource = objDataView;
            ListViewCommon.BindData(objListView, objDataView, sPK_Field, sGroup_Field, itemInvoke);
        }

        public void BindData(DataView objDataView, string sPK_Field, string sGroup_Field)
        {
            BindData(objDataView, sPK_Field, sGroup_Field, null);
        }

        private void objListView_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            if (objListView.SelectedItems.Count > 0)
            {
                if ((m_SelectMethod != null))
                    m_SelectMethod.Invoke();
            }
        }

        private void objListView_DrawColumnHeader(object sender, System.Windows.Forms.DrawListViewColumnHeaderEventArgs e)
        {
            e.DrawBackground();
            StringFormat format = new StringFormat();
            format.Alignment = StringAlignment.Near;
            format.LineAlignment = StringAlignment.Center;
            e.Graphics.DrawString(e.Header.Text, FormGlobals.Control_StyleFont(e.Font, FormGlobals.CS_GRID_HEADER), new SolidBrush(FormGlobals.Control_StyleColor(e.ForeColor, FormGlobals.CS_GRID_HEADER)), e.Bounds, format);
        }

        private void objListView_DrawItem(object sender, System.Windows.Forms.DrawListViewItemEventArgs e)
        {
            if ((e.Item.Selected))
            {
                e.Graphics.FillRectangle(new SolidBrush(Color.DarkOrange), e.Bounds);
            }
            e.DrawDefault = true;
        }

        private void objListView_DrawSubItem(object sender, System.Windows.Forms.DrawListViewSubItemEventArgs e)
        {
            e.DrawDefault = true;
        }
    }

    public static class ListViewCommon
    {
        //*******************************************************************
        // Purpose: Module chứa các hàm, thủ tục dùng chung cho ListView
        // Notes: 
        // History:
        // [Programer] [DD-MMM-YYYY] [Action]
        // LuanNH Unknow Created
        //******************************************************************* 

        public static ListViewItem.ListViewSubItem GetSubItem(ListViewItem lvItem, string sColumnName)
        {
            //Purpose: 
            // Lấy đối tượng SubItem theo tên của cột dữ liệu
            //Parameters: 
            // lvItem : đối tượng ListView
            // sColumnName : tên cột dữ liệu
            //Notes:
            // Giá trị trả về là đối tượng SubItem

            if (lvItem.SubItems.ContainsKey(sColumnName))
            {
                return lvItem.SubItems[sColumnName];
            }
            else
            {
                ListViewHeader clm = null;
                for (int i = 0; i <= lvItem.ListView.Columns.Count - 1; i++)
                {
                    clm = (ListViewHeader)lvItem.ListView.Columns[i];
                    if (sColumnName.ToUpper() == clm.DataField.ToUpper())
                    {
                        if (i > lvItem.SubItems.Count - 1)
                        {
                            for (int j = lvItem.SubItems.Count; j <= i; j++)
                            {
                                lvItem.SubItems.Add("");
                            }
                        }
                        return lvItem.SubItems[i];
                    }
                }
                return null;
            }
        }

        public static string GetSubItemText(ListViewItem lvItem, string sColumnName)
        {
            //Purpose: 
            // Lấy giá trị Text của đối tượng SubItem theo tên của cột dữ liệu
            //Parameters: 
            // lvItem : đối tượng ListView
            // sColumnName : tên cột dữ liệu
            //Notes:
            //

            if (lvItem.SubItems.ContainsKey(sColumnName))
            {
                return lvItem.SubItems[sColumnName].Text;
            }
            else
            {
                ListViewItem.ListViewSubItem subItem = default(ListViewItem.ListViewSubItem);
                subItem = GetSubItem(lvItem, sColumnName);
                if ((subItem != null))
                {
                    return subItem.Text;
                }
                else
                {
                    throw new Exception(string.Format("SubItem with key '{0}' not found", sColumnName));
                }
            }
        }

        public static string CopyData(ListView objListView, bool bIncludeGroup = true)
        {
            //Purpose: 
            // Lấy tất cả giá trị của các item trong ListView dưới dạng text có format
            //Parameters: 
            // lvItem : đối tượng ListView
            // bIncludeGroup : có lấy cả ListViewGroup hay không
            //Notes:
            //
            string sTemp = null;
            string sGroupName = null;
            bool bUseGroup = (objListView.ShowGroups && bIncludeGroup);

            System.Text.StringBuilder sBuilder = new System.Text.StringBuilder();
            foreach (ColumnHeader lvColumn in objListView.Columns)
            {
                if (string.IsNullOrEmpty(sTemp))
                {
                    sTemp = lvColumn.Text;
                }
                else
                {
                    sTemp += Globals.vbTab + lvColumn.Text;
                }
            }
            sBuilder.Append(sTemp);
            foreach (ListViewItem lvItem in objListView.Items)
            {
                if (bUseGroup && objListView.Groups.Count > 0)
                {
                    if ((lvItem.Group != null) && sGroupName != lvItem.Group.Name)
                    {
                        sGroupName = lvItem.Group.Name;
                        sBuilder.Append(Globals.vbCrLf + lvItem.Group.Header);
                    }
                }
                sTemp = "";
                for (int i = 0; i <= lvItem.SubItems.Count - 1; i++)
                {
                    if (string.IsNullOrEmpty(sTemp))
                    {
                        sTemp = lvItem.SubItems[i].Text;
                    }
                    else
                    {
                        sTemp += Globals.vbTab + lvItem.SubItems[i].Text;
                    }
                }
                sBuilder.Append(Globals.vbCrLf + sTemp);
            }
            return sBuilder.ToString();
        }

        public static long MoveAll(ListView lstSource, ListView lstDest)
        {
            //Purpose: 
            // Hàm để chuyển ListViewItem từ ListView này sang ListView khác (move all)
            //Parameters: 
            // lstSource : ListView nguồn
            // lstDest : ListView nguồn đích
            //Notes:
            long iReturn = 0;
            iReturn = lstSource.Items.Count;
            if (iReturn > 0)
            {
                lstSource.BeginUpdate();
                lstDest.BeginUpdate();
                foreach (ListViewItem itm in lstSource.Items)
                {
                    lstSource.Items.Remove(itm);
                    itm.Selected = false;
                    lstDest.Items.Add(itm);
                }
                lstSource.EndUpdate();
                lstDest.EndUpdate();
            }
            return iReturn;
        }

        public static long MoveSelect(ListView lstSource, ListView lstDest)
        {
            //Purpose: 
            // Hàm để chuyển ListViewItem từ ListView này sang ListView khác (move select)
            //Parameters: 
            // lstSource : ListView nguồn
            // lstDest : ListView nguồn đích
            //Notes:
            long iReturn = 0;
            iReturn = lstSource.SelectedItems.Count;
            if (iReturn > 0)
            {
                lstSource.BeginUpdate();
                lstDest.BeginUpdate();
                foreach (ListViewItem itm in lstSource.SelectedItems)
                {
                    lstSource.Items.Remove(itm);
                    itm.Selected = false;
                    lstDest.Items.Add(itm);
                }
                lstSource.EndUpdate();
                lstDest.EndUpdate();
            }
            return iReturn;
        }

        public static ListViewItem AddItem(ListView objListView, object objData, string sPK_Field = "")
        {
            //Purpose: 
            // Ham Add Item cho ListView theo ColumnHeader
            //Parameters: 
            // objListView : đối tượng ListView
            // objData : object data 
            //Notes

            ListViewItem lvItem = default(ListViewItem);
            string sColumnName = null;
            string sValue = null;
            foreach (ListViewHeader clm in objListView.Columns)
            {
                sColumnName = clm.DataField;
                if (objData is IDataReader)
                {
                    sValue = Globals.DB_GetString(((IDataReader)objData)[sColumnName]);
                }
                else
                {
                    sValue = Globals.Object_GetDisplayValue(Globals.Object_GetPropertyValue(objData, sColumnName));
                }
                if (lvItem == null)
                {
                    lvItem = objListView.Items.Add(sValue);
                }
                else
                {
                    lvItem.SubItems.Add(sValue);
                }
            }
            //Set Key value
            if (!string.IsNullOrEmpty(sPK_Field))
            {
                if (objData is IDataReader)
                {
                    lvItem.Name = Globals.DB_GetString(((IDataReader)objData)[sPK_Field]);
                }
                else
                {
                    lvItem.Name = Globals.Object_GetDisplayValue(Globals.Object_GetPropertyValue(objData, sPK_Field));
                }
            }
            if (!(objData is IDataReader))
            {
                lvItem.Tag = objData;
            }
            return lvItem;
        }

        public static void UpdateItem(ListViewItem lvItem, object objData, string sPK_Field = "")
        {
            //Purpose: 
            // Ham Update Item cho ListViewItem theo ColumnHeader
            //Parameters: 
            // lvItem : đối tượng ListViewItem
            // objData : object data 
            //Notes

            string sColumnName = null;
            string sValue = null;
            int i = 0;
            foreach (ListViewHeader clm in lvItem.ListView.Columns)
            {
                sColumnName = clm.DataField;
                sValue = Globals.Object_GetDisplayValue(Globals.Object_GetPropertyValue(objData, sColumnName));
                lvItem.SubItems[i].Text = sValue;
                i += 1;
            }
            //Set Key value
            if (!string.IsNullOrEmpty(sPK_Field))
            {
                lvItem.Name = Globals.Object_GetDisplayValue(Globals.Object_GetPropertyValue(objData, sPK_Field));
            }
            lvItem.Tag = objData;
        }

        public static void BindData(ListView objListView, IDataReader objReader, string sPK_Field = "")
        {
            BindData(objListView, null, objReader, sPK_Field);
        }

        public static void BindData(ListView objListView, ListViewGroup objGroup, IDataReader objReader, string sPK_Field = "")
        {
            //Purpose: 
            // Ham Add All Item cho ListView theo ColumnHeader
            //Parameters: 
            // objListView : đối tượng ListView
            // objReader : object IdataReader
            //Notes
            //
            if (objListView.ListViewItemSorter is ListViewColumnSorter)
            {
                ((ListViewColumnSorter)objListView.ListViewItemSorter).Reset();
            }
            //
            string sColumnName = null;
            string sValue = null;
            object objValue = null;
            int iPK = -1;
            if (!string.IsNullOrEmpty(sPK_Field))
            {
                iPK = Globals.Reader_ColumnIndex(objReader, sPK_Field);
                if (iPK == -1)
                    throw new Exception("Invalid primary key column '" + sPK_Field + "'");
            }
            try
            {
                //
                objListView.Items.Clear();
                objListView.BeginUpdate();
                ListViewItem lvItem = default(ListViewItem);
                while (objReader.Read())
                {
                    lvItem = null;
                    foreach (ListViewHeader clm in objListView.Columns)
                    {
                        sColumnName = clm.DataField;
                        if (sColumnName == "@STT")
                        {
                            sValue = (objListView.Items.Count + 1).ToString();
                            objValue = null;
                        }
                        else
                        {
                            if (clm.DataIndex == -1)
                            {
                                clm.DataIndex = Globals.Reader_ColumnIndex(objReader, sColumnName);
                                clm.DataType = objReader.GetFieldType(clm.DataIndex).Name;
                            }
                            objValue = objReader[clm.DataIndex];
                            sValue = Globals.Object_GetDisplayValue(objValue);
                        }
                        if (lvItem == null)
                        {
                            lvItem = objListView.Items.Add(sValue);
                            if (iPK > -1)
                            {
                                lvItem.Tag = objReader[iPK];
                            }
                            lvItem.Group = objGroup;
                            if (clm.KeepValue)
                                lvItem.SubItems[0].Tag = objValue;
                        }
                        else
                        {
                            ListViewItem.ListViewSubItem subItem = lvItem.SubItems.Add(sValue);
                            if (clm.KeepValue)
                                subItem.Tag = objValue;
                        }
                    }
                }
            }
            finally
            {
                Globals.Reader_Close(objReader);
                objListView.EndUpdate();
            }
        }

        public static void BindData(ListView objListView, DataTable objDataTable, string sPK_Field)
        {
            BindData(objListView, objDataTable, sPK_Field, "");
        }

        public static void BindData(ListView objListView, DataTable objDataTable, string sPK_Field, string sGroup_Field)
        {
            BindData(objListView, objDataTable.DefaultView, sPK_Field, sGroup_Field, null);
        }

        //Private Sub BindData(ByVal objListView As ListView, ByVal objGroup As ListViewGroup, ByVal objDataTable As DataTable, Optional ByVal sPK_Field As String = "")
        // BindData(objListView, objGroup, objDataTable.DefaultView, sPK_Field)
        //End Sub

        public static void BindData(ListView objListView, DataView objDataView, string sPK_Field = "")
        {
            BindData(objListView, objDataView, sPK_Field, "", null);
        }

        public static void BindData(ListView objListView, DataView objDataView, string sPK_Field, string sGroup_Field, ListItemInvoker itemInvoke)
        {
            //Purpose: 
            // Ham Add All Item cho ListView theo ColumnHeader
            //Parameters: 
            // objListView : đối tượng ListView
            // objDataView : object DataView
            //Notes
            //
            if (objListView.ListViewItemSorter is ListViewColumnSorter)
            {
                ((ListViewColumnSorter)objListView.ListViewItemSorter).Reset();
            }
            //
            string sColumnName = null;
            string sDisplayValue = null;
            object objValue = null;
            int iPK = -1;
            //
            if (!string.IsNullOrEmpty(sPK_Field))
            {
                iPK = objDataView.Table.Columns.IndexOf(sPK_Field);
                if (iPK == -1)
                    throw new Exception("Invalid primary key column '" + sPK_Field + "'");
            }
            //
            try
            {
                objListView.Items.Clear();
                objListView.Groups.Clear();
                objListView.BeginUpdate();
                objListView.ShowGroups = !string.IsNullOrEmpty(sGroup_Field);
                ListViewItem lvItem = default(ListViewItem);
                for (int i = 0; i <= objDataView.Count - 1; i++)
                {
                    lvItem = null;
                    foreach (ListViewHeader clm in objListView.Columns)
                    {
                        sColumnName = clm.DataField;
                        if (sColumnName == "@STT")
                        {
                            sDisplayValue = (objListView.Items.Count + 1).ToString();
                            objValue = null;
                        }
                        else if (sColumnName.Contains("+"))
                        {
                            string[] arrColumns = sColumnName.Split(new char[]{'+'});
                            sDisplayValue = "";
                            foreach (string sColumnName_loopVariable in arrColumns)
                            {
                                sColumnName = sColumnName_loopVariable;
                                if (objDataView.Table.Columns.Contains(sColumnName))
                                {
                                    sDisplayValue += Globals.DB_GetString(objDataView[i][sColumnName]);
                                }
                                else
                                {
                                    sDisplayValue += sColumnName;
                                }
                            }
                            objValue = sDisplayValue;
                        }
                        else
                        {
                            if (clm.DataIndex == -1)
                            {
                                clm.DataIndex = objDataView.Table.Columns.IndexOf(sColumnName);
                                if (clm.DataIndex == -1)
                                {
                                    throw new Exception("Data column '" + sColumnName + "' not found in table");
                                }
                                clm.DataType = objDataView.Table.Columns[clm.DataIndex].DataType.Name;
                            }
                            objValue = objDataView[i][clm.DataIndex];
                            sDisplayValue = Globals.Object_GetDisplayValue(objValue);
                        }
                        if (lvItem == null)
                        {
                            lvItem = objListView.Items.Add(sDisplayValue);
                            if (iPK > -1)
                            {
                                lvItem.Tag = objDataView[i][sPK_Field];
                                lvItem.Name = lvItem.Tag.ToString();
                            }
                            if (!string.IsNullOrEmpty(sGroup_Field))
                            {
                                string keyField = sGroup_Field;
                                string textField = sGroup_Field;
                                if (sGroup_Field.Contains(";"))
                                {
                                    keyField = sGroup_Field.Split(new char[]{';'})[0];
                                    textField = sGroup_Field.Split(new char[] { ';' })[1];
                                }
                                string groupKey = Globals.DB_GetString(objDataView[i][keyField], "{DBNull.Value}");
                                ListViewGroup objGroup = objListView.Groups[groupKey];
                                if (objGroup == null)
                                {
                                    objGroup = new ListViewGroup(groupKey, objDataView[i][textField].ToString());
                                    objListView.Groups.Add(objGroup);
                                    objGroup.Tag = objDataView[i][keyField];
                                }
                                lvItem.Group = objGroup;
                            }
                            //
                            if (clm.KeepValue)
                                lvItem.SubItems[0].Tag = objValue;
                            //
                            int index = lvItem.Index;
                            if ((lvItem.Group != null))
                            {
                                index = lvItem.Group.Items.IndexOf(lvItem);
                            }
                            if (!((index % 2) == 0))
                            {
                                lvItem.BackColor = FormGlobals.App_GetColor(FormGlobals.CS_GRID_ROW_ALTER);
                            }
                        }
                        else
                        {
                            ListViewItem.ListViewSubItem subItem = lvItem.SubItems.Add(sDisplayValue);
                            subItem.Name = sColumnName;
                            if (clm.KeepValue)
                                subItem.Tag = objValue;
                            if ((itemInvoke != null))
                            {
                                subItem.Font = lvItem.Font;
                                subItem.BackColor = lvItem.BackColor;
                                subItem.ForeColor = lvItem.ForeColor;
                            }
                        }
                    }
                    if ((itemInvoke != null))
                    {
                        lvItem.UseItemStyleForSubItems = false;
                        itemInvoke.Invoke(lvItem);
                    }
                }
                //
                objListView.ShowGroups = (objListView.Groups.Count > 0);
            }
            finally
            {
                objListView.EndUpdate();
            }
        }

        //Private Sub BindData(ByVal objListView As ListView, ByVal objGroup As ListViewGroup, ByVal objDataView As DataView, Optional ByVal sPK_Field As String = "")
        // 'Purpose: 
        // ' Ham Add All Item cho ListView theo ColumnHeader
        // 'Parameters: 
        // ' objListView : đối tượng ListView
        // ' objDataView : object DataView
        // 'Notes
        // '
        // If TypeOf objListView.ListViewItemSorter Is ListViewColumnSorter Then
        // DirectCast(objListView.ListViewItemSorter, ListViewColumnSorter).Reset()
        // End If
        // '
        // Dim sColumnName, sDisplayValue As String
        // Dim objValue As Object
        // Dim iPK As Integer = -1
        // '
        // If Not String.IsNullOrEmpty(sPK_Field) Then
        // iPK = objDataView.Table.Columns.IndexOf(sPK_Field)
        // If iPK = -1 Then Throw New Exception("Invalid primary key column '" + sPK_Field + "'")
        // End If
        // '
        // Try
        // objListView.Items.Clear()
        // objListView.BeginUpdate()
        // Dim lvItem As ListViewItem
        // For i As Integer = 0 To objDataView.Count - 1
        // lvItem = Nothing
        // For Each clm As ListViewHeader In objListView.Columns
        // sColumnName = clm.DataField
        // If sColumnName = "@STT" Then
        // sDisplayValue = objListView.Items.Count + 1
        // objValue = Nothing
        // Else
        // If clm.DataIndex = -1 Then
        // clm.DataIndex = objDataView.Table.Columns.IndexOf(sColumnName)
        // clm.DataType = objDataView.Table.Columns(clm.DataIndex).DataType.Name
        // End If
        // objValue = objDataView.Item(i).Item(clm.DataIndex)
        // sDisplayValue = Object_GetDisplayValue(objValue)
        // End If
        // If lvItem Is Nothing Then
        // lvItem = objListView.Items.Add(sDisplayValue)
        // If iPK > -1 Then
        // lvItem.Tag = objDataView.Item(i).Item(sPK_Field)
        // lvItem.Name = lvItem.Tag
        // End If
        // lvItem.Group = objGroup
        // If clm.KeepValue Then lvItem.SubItems(0).Tag = objValue
        // Else
        // Dim subItem As ListViewItem.ListViewSubItem = lvItem.SubItems.Add(sDisplayValue)
        // subItem.Name = sColumnName
        // If clm.KeepValue Then subItem.Tag = objValue
        // End If
        // Next
        // Next
        // Finally
        // objListView.EndUpdate()
        // End Try
        //End Sub

        private static void BindData(ListView objListView, ListViewGroup objGroup, ArrayList arrObject, string sPK_Field = "")
        {
            //Purpose: 
            // Ham Add All Item cho ListView theo ColumnHeader
            //Parameters: 
            // objListView : đối tượng ListView
            // objReader : object ArrayList
            //Notes
            //
            if (objListView.ListViewItemSorter is ListViewColumnSorter)
            {
                ((ListViewColumnSorter)objListView.ListViewItemSorter).Reset();
            }
            //
            string sColumnName = null;
            string sValue = null;
            object objValue = null;
            ListViewItem lvItem = default(ListViewItem);
            //
            int iPK = -1;
            if (arrObject.Count > 0 && !string.IsNullOrEmpty(sPK_Field))
            {
                iPK = Globals.Object_GetPropertyIndex(arrObject[0].GetType(), ref sPK_Field);
                if (iPK == -1)
                    throw new Exception("Invalid primary key property '" + sPK_Field + "'");
            }
            //
            try
            {
                objListView.BeginUpdate();
                objListView.Items.Clear();
                //
                //List<PropertyInfo> arrProperty = default(List<PropertyInfo>);

                ArrayList arrProperty = default(ArrayList);

                if (arrObject.Count > 0)
                {
                    arrProperty = CBO.GetPropertyInfo(arrObject[0].GetType());
                }

                foreach (object objData in arrObject)
                {
                    lvItem = null;
                    foreach (ListViewHeader clm in objListView.Columns)
                    {
                        sColumnName = clm.DataField;
                        if (sColumnName == "@STT")
                        {
                            sValue = (objListView.Items.Count + 1).ToString();
                            objValue = null;
                        }
                        else
                        {
                            if (clm.DataIndex == -1)
                            {
                                clm.DataIndex = Globals.Object_GetPropertyIndex(arrProperty, ref sColumnName);
                                clm.DataType = ((PropertyInfo) arrProperty[clm.DataIndex]).PropertyType.Name;
                            }
                            objValue = ((PropertyInfo)arrProperty[clm.DataIndex]).GetValue(objData, null);
                            //Object_GetPropertyValue(objData, clm.DataIndex)
                            sValue = Globals.Object_GetDisplayValue(objValue);
                        }
                        if (lvItem == null)
                        {
                            lvItem = objListView.Items.Add(sValue);
                            if (iPK > -1)
                            {
                                lvItem.Tag = Globals.Object_GetPropertyValue(objData, (iPK));
                            }
                            lvItem.Group = objGroup;
                            if (clm.KeepValue)
                                lvItem.SubItems[0].Tag = objValue;
                        }
                        else
                        {
                            ListViewItem.ListViewSubItem subItem = lvItem.SubItems.Add(sValue);
                            if (clm.KeepValue)
                                subItem.Tag = objValue;
                        }
                    }
                }
            }
            finally
            {
                objListView.EndUpdate();
            }
        }

    }

